import { defineStore } from 'pinia';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { socketService } from '../utils/socket-utils';

// 定义接口类型
export interface Friend {
  friend_id: number;
  friend_user_id: number;
  username: string;
  avatar_url: string | null;
  login: number;
  unreadCount: number;
}

interface Message {
  message_id: number;
  sender_id: number;
  receiver_id: number;
  content: string;
  created_at: string;
  is_read: number;
}

interface ChatState {
  friends: Friend[];
  selectedFriend: Friend | null;
  messages: Message[];
  currentUserId: number;
  isLoading: boolean;
  error: string | null;
}

/**
 * 聊天模块状态管理
 */
export const useChatStore = defineStore('chat', {
  state: (): ChatState => ({
    friends: [],
    selectedFriend: null,
    messages: [],
    currentUserId: 0,
    isLoading: false,
    error: null
  }),

  getters: {
    /**
     * 获取过滤后的好友列表
     * @param state - 状态对象
     * @returns 好友列表
     */
    filteredFriends: (state) => state.friends,

    /**
     * 检查是否有未读消息
     * @param state - 状态对象
     * @returns 是否有未读消息
     */
    hasUnreadMessages: (state) => {
      return state.friends.some(friend => friend.unreadCount > 0);
    },

    /**
     * 获取总未读消息数
     * @param state - 状态对象
     * @returns 总未读消息数
     */
    totalUnreadCount: (state) => {
      return state.friends.reduce((total, friend) => total + friend.unreadCount, 0);
    }
  },

  actions: {
    /**
     * 初始化聊天状态
     */
    async initialize() {
      try {
        console.log(`[${new Date().toLocaleString()}] [INFO] 初始化聊天状态`);
        this.isLoading = true;
        this.error = null;

        // 获取当前用户ID
        const userStr = localStorage.getItem('user');
        if (userStr) {
          const user = JSON.parse(userStr);
          this.currentUserId = user.id;

          // 加载好友列表
          await this.loadFriends();

          // 初始化WebSocket连接
          this.initWebSocket();
        } else {
          throw new Error('用户未登录');
        }
      } catch (error) {
        console.error(`[${new Date().toLocaleString()}] [ERROR] 初始化聊天状态失败:`, error);
        this.error = error instanceof Error ? error.message : '初始化聊天状态失败';
        ElMessage.error(this.error);
      } finally {
        this.isLoading = false;
      }
    },

    /**
     * 加载好友列表
     */
    async loadFriends() {
      try {
        console.log(`[${new Date().toLocaleString()}] [INFO] 加载好友列表`);
        this.isLoading = true;
        this.error = null;

        const response = await axios.get('/api/chat/friends', {
          headers: {
            Authorization: `Bearer ${localStorage.getItem('token')}`
          }
        });

        this.friends = response.data.friends;
        console.log(`[${new Date().toLocaleString()}] [INFO] 成功加载好友列表，共 ${this.friends.length} 位好友`);
      } catch (error) {
        console.error(`[${new Date().toLocaleString()}] [ERROR] 加载好友列表失败:`, error);
        this.error = error instanceof Error ? error.message : '加载好友列表失败';
        ElMessage.error(this.error);
      } finally {
        this.isLoading = false;
      }
    },

    /**
     * 选择好友
     * @param friend - 好友对象
     */
    async selectFriend(friend: Friend) {
      try {
        console.log(`[${new Date().toLocaleString()}] [INFO] 选择好友: ${friend.username}`);
        this.selectedFriend = friend;
        this.messages = [];
        this.isLoading = true;
        this.error = null;

        const response = await axios.get(`/api/chat/messages/${friend.friend_user_id}`, {
          headers: {
            Authorization: `Bearer ${localStorage.getItem('token')}`
          }
        });

        this.messages = response.data.messages;
        console.log(`[${new Date().toLocaleString()}] [INFO] 成功加载与 ${friend.username} 的聊天记录，共 ${this.messages.length} 条消息`);

        // 标记消息为已读
        if (friend.unreadCount > 0) {
          await this.markAsRead(friend.friend_user_id);
          friend.unreadCount = 0;
        }
      } catch (error) {
        console.error(`[${new Date().toLocaleString()}] [ERROR] 选择好友失败:`, error);
        this.error = error instanceof Error ? error.message : '加载聊天记录失败';
        ElMessage.error(this.error);
      } finally {
        this.isLoading = false;
      }
    },

    /**
     * 发送消息
     * @param receiverId - 接收者ID
     * @param content - 消息内容
     * @returns 发送的消息
     */
    async sendMessage(receiverId: number, content: string) {
      try {
        console.log(`[${new Date().toLocaleString()}] [INFO] 发送消息给 ${receiverId}: ${content.substring(0, 20)}...`);
        this.error = null;

        // 乐观更新 - 先添加到消息列表
        const tempMessage: Partial<Message> = {
          sender_id: this.currentUserId,
          receiver_id: receiverId,
          content,
          created_at: new Date().toISOString(),
          is_read: 0
        };
        this.messages.push(tempMessage as Message);

        // 实际发送消息
        const response = await axios.post(
          '/api/chat/messages',
          { receiverId, content },
          { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } }
        );

        // 替换临时消息为实际消息
        const index = this.messages.findIndex(
          m => m.content === content && m.created_at === tempMessage.created_at
        );
        if (index !== -1) {
          this.messages[index] = response.data.message;
        }

        console.log(`[${new Date().toLocaleString()}] [INFO] 消息发送成功`);
        return response.data.message;
      } catch (error) {
        console.error(`[${new Date().toLocaleString()}] [ERROR] 发送消息失败:`, error);
        this.error = error instanceof Error ? error.message : '发送消息失败';
        ElMessage.error(this.error);

        // 移除乐观更新的消息
        const index = this.messages.findIndex(
          m => m.sender_id === this.currentUserId && m.content === content
        );
        if (index !== -1) {
          this.messages.splice(index, 1);
        }

        throw error;
      }
    },

    /**
     * 标记消息为已读
     * @param friendId - 好友ID
     */
    async markAsRead(friendId: number) {
      try {
        console.log(`[${new Date().toLocaleString()}] [INFO] 标记与好友 ${friendId} 的消息为已读`);
        this.error = null;

        await axios.put(
          '/api/chat/messages/read',
          { friendId },
          { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } }
        );

        console.log(`[${new Date().toLocaleString()}] [INFO] 消息已标记为已读`);
      } catch (error) {
        console.error(`[${new Date().toLocaleString()}] [ERROR] 标记消息为已读失败:`, error);
        this.error = error instanceof Error ? error.message : '标记消息为已读失败';
      }
    },

    /**
     * 处理新消息
     * @param message - 新消息
     */
    handleNewMessage(message: Message) {
      console.log(`[${new Date().toLocaleString()}] [INFO] 收到新消息:`, message);

      // 如果是当前选中的好友的消息
      if (this.selectedFriend && this.selectedFriend.friend_user_id === message.sender_id) {
        this.messages.push(message);

        // 标记为已读
        if (message.receiver_id === this.currentUserId) {
          this.markAsRead(message.sender_id);
        }
      } else {
        // 更新好友的未读消息数
        const friendIndex = this.friends.findIndex(f => f.friend_user_id === message.sender_id);
        if (friendIndex !== -1) {
          this.friends[friendIndex].unreadCount++;
        }

        // 显示通知
        const friend = this.friends.find(f => f.friend_user_id === message.sender_id);
        ElMessage({
          message: `收到来自 ${friend ? friend.username : '未知用户'} 的新消息`,
          type: 'info',
          duration: 3000
        });
      }
    },

    /**
     * 初始化WebSocket连接
     */
    initWebSocket() {
      if (this.currentUserId) {
        socketService.init(this.currentUserId);

        // 监听新消息事件
        socketService.on('newMessage', (message: Message) => {
          this.handleNewMessage(message);
        });
      }
    },

    /**
     * 清理聊天状态
     */
    cleanup() {
      socketService.close();
      socketService.off('newMessage');
      this.friends = [];
      this.selectedFriend = null;
      this.messages = [];
      this.currentUserId = 0;
      console.log(`[${new Date().toLocaleString()}] [INFO] 聊天状态已清理`);
    }
  }
});